package handlers

import (
	"io"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"

	"android-retrace/internal/config"
	"android-retrace/internal/websocket"

	//"android-retrace/internal/session"
	//"encoding/json"
	//"fmt"

	"github.com/gin-gonic/gin"
)

type Handler struct {
	wsManager *websocket.Manager
}

type UploadResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
	Token   string `json:"token,omitempty"`
}

type ParseRequest struct {
	Token     string `json:"token"`
	StackInfo string `json:"stackInfo"`
}

type ParseResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
	Result  string `json:"result,omitempty"`
}

func NewHandler(wsManager *websocket.Manager) *Handler {
	return &Handler{
		wsManager: wsManager,
	}
}

func (h *Handler) WebSocket(c *gin.Context) {
	h.wsManager.HandleWebSocket(c)
}

func (h *Handler) UploadFile(c *gin.Context) {
	// 从查询参数获取token
	token := c.Query("token")
	if token == "" {
		c.JSON(http.StatusBadRequest, UploadResponse{
			Success: false,
			Message: "缺少token参数",
		})
		return
	}

	// 获取上传的文件
	file, _, err := c.Request.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, UploadResponse{
			Success: false,
			Message: "获取上传文件失败: " + err.Error(),
		})
		return
	}
	defer file.Close()

	// 创建临时目录
	tempDir := filepath.Join("temp", token)
	if err := os.MkdirAll(tempDir, 0o755); err != nil {
		c.JSON(http.StatusInternalServerError, UploadResponse{
			Success: false,
			Message: "创建临时目录失败: " + err.Error(),
		})
		return
	}

	// 保存文件
	// filePath := filepath.Join(tempDir, header.Filename)
	filePath := filepath.Join(tempDir, "mapping.txt") // 统一命名为 mapping.txt
	dst, err := os.Create(filePath)
	if err != nil {
		c.JSON(http.StatusInternalServerError, UploadResponse{
			Success: false,
			Message: "创建文件失败: " + err.Error(),
		})
		return
	}
	defer dst.Close()

	if _, err := io.Copy(dst, file); err != nil {
		c.JSON(http.StatusInternalServerError, UploadResponse{
			Success: false,
			Message: "保存文件失败: " + err.Error(),
		})
		return
	}

	config.Cfg.Statistics.TrackUpload += 1
	config.SaveConfig()

	c.JSON(http.StatusOK, UploadResponse{
		Success: true,
		Message: "文件上传成功",
		Token:   token,
	})
}

func (h *Handler) ParseLog(c *gin.Context) {
	var req ParseRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, ParseResponse{
			Success: false,
			Message: "请求参数错误: " + err.Error(),
		})
		return
	}

	// 检查临时目录是否存在
	tempDir := filepath.Join("temp", req.Token)
	if _, err := os.Stat(tempDir); os.IsNotExist(err) {
		c.JSON(http.StatusBadRequest, ParseResponse{
			Success: false,
			Message: "临时目录不存在，请先上传文件",
		})
		return
	}
	/*
		// 查找上传的文件
		var filePath string
		files, err := filepath.Glob(filepath.Join(tempDir, "*"))
		if err != nil || len(files) == 0 {
			c.JSON(http.StatusBadRequest, ParseResponse{
				Success: false,
				Message: "未找到上传的文件",
			})
			return
		}

		// 使用第一个文件
		filePath = files[0]
	*/

	// 保存堆栈信息到文件
	stackFile := filepath.Join(tempDir, "stack.txt")
	if err := os.WriteFile(stackFile, []byte(req.StackInfo), 0o644); err != nil {
		c.JSON(http.StatusInternalServerError, ParseResponse{
			Success: false,
			Message: "保存堆栈信息失败: " + err.Error(),
		})
		return
	}

	filePath := filepath.Join(tempDir, "mapping.txt") // 统一命名为 mapping.txt

	// 调用解析器，改为执行 Java 命令
	javaPath := config.Cfg.Java.Path
	jarPath := config.Cfg.Java.Jar
	cmd := exec.Command(
		javaPath,
		"-jar",
		jarPath,
		filePath,
		stackFile,
	)
	output, err := cmd.CombinedOutput()
	if err != nil {
		c.JSON(http.StatusInternalServerError, ParseResponse{
			Success: false,
			Message: "解析日志失败: " + err.Error() + "\n" + string(output),
		})
		return
	}

	config.Cfg.Statistics.TrackParse += 1
	config.SaveConfig()

	c.JSON(http.StatusOK, ParseResponse{
		Success: true,
		Message: "解析成功",
		Result:  string(output),
	})
}
